package com.satan.vote.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.satan.vote.constant.JwtConstant;
import com.satan.vote.dto.WxUserInfoDTO;
import com.satan.vote.entity.WxUserInfo;
import com.satan.vote.mapper.WxUserInfoMapper;
import com.satan.vote.properties.WxProperties;
import com.satan.vote.service.WxUserInfoService;
import com.satan.vote.util.DateUtil;
import com.satan.vote.util.HttpClientUtil;
import com.satan.vote.util.JwtUtils;
import com.satan.vote.util.StringUtil;
import com.satan.vote.vo.ResultVO;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName WxUserInfoServiceImpl
 * @Description TODO
 * @date 2023/8/10 13:36
 * @Version 1.0
 */
@Service
@Slf4j
public class WxUserInfoServiceImpl extends ServiceImpl<WxUserInfoMapper, WxUserInfo> implements WxUserInfoService {
    @Autowired
    private WxProperties wxProperties;
    @Autowired
    private HttpClientUtil httpClientUtil;
    @Value("${userImagesFilePath}")
    private String userImagesFilePath;
    @Autowired
    private ResourceLoader resourceLoader;

    @Override
    @Transactional
    public ResultVO wxLogin(WxUserInfoDTO wxUserInfoDTO) {
        System.out.println(wxUserInfoDTO);
        String jscode2sessionUrl = wxProperties.getJscode2sessionUrl() + "?appid=" + wxProperties.getAppid() + "&secret=" + wxProperties.getSecret() + "&js_code=" + wxUserInfoDTO.getCode() + "&grant_type=authorization_code";
        log.info("jscode2sessionUrl={}", jscode2sessionUrl);
        String result = httpClientUtil.sendHttpGet(jscode2sessionUrl);
        System.out.println(result);
        JSONObject jsonObject = JSON.parseObject(result);
        String openid = jsonObject.get("openid").toString();
        System.out.println(openid);
        // 插入用户到数据库 假如说 用户不存在 我们插入用户 如果用户存在 我们更新用户

        QueryWrapper queryWrapper = QueryWrapper.create().where(WxUserInfo::getOpenid).eq(openid);
        WxUserInfo wxUserInfo = getOne(queryWrapper);

        if (wxUserInfo == null) {
            System.out.println("不存在 插入用户");
            wxUserInfo = new WxUserInfo();
            wxUserInfo.setOpenid(openid);
            wxUserInfo.setRegisterDate(LocalDateTime.now());
            wxUserInfo.setLastLoginDate(LocalDateTime.now());
            wxUserInfo.setStatus("0");
            save(wxUserInfo);
        } else {
            log.info("存在 更新用户");
            wxUserInfo.setLastLoginDate(LocalDateTime.now());
            updateById(wxUserInfo);
        }

        if (wxUserInfo != null && "1".equals(wxUserInfo.getStatus())) { // 被禁用
            return ResultVO.fail(400, "用户被禁用，请联系管理员！");
        } else {
            // 利用 jwt 生成 token 返回到前端
            String token = JwtUtils.createJWT(openid, wxUserInfo.getNickName(), JwtConstant.JWT_TTL);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("token", token);
            resultMap.put("openid", openid);
            return ResultVO.success(resultMap);
        }

    }

    @Override
    public ResultVO getUserInfo(String token) {
        System.out.println("token=" + token);
        Claims claims = JwtUtils.validateJWT(token).getClaims();
        System.out.println("openid=" + claims.getId());
        QueryWrapper queryWrapper = QueryWrapper.create().where(WxUserInfo::getOpenid).eq(claims.getId());
        WxUserInfo currentUser = getOne(queryWrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("currentUser", currentUser);
        return ResultVO.success(map);
    }

    @Override
    public ResultVO updateNickName(WxUserInfo wxUserInfo, String token) {
        System.out.println("wxUserInfo = " + wxUserInfo);
        if (StringUtil.isNotEmpty(wxUserInfo.getNickName())) {
            Claims claims = JwtUtils.validateJWT(token).getClaims();
            QueryWrapper queryWrapper = QueryWrapper.create().where(WxUserInfo::getOpenid).eq(claims.getId());
            boolean update = update(wxUserInfo, queryWrapper);
            if (update) {
                return ResultVO.success(null);
            } else {
                return ResultVO.fail(1000, "更新失败");
            }
        }
        return ResultVO.fail(1000, "更新参数为空");
    }

    @Override
    @Transactional
    public ResultVO uploadUserImage(MultipartFile userImage, String token) {
        System.out.println("filename:" + userImage.getName());
        Map<String, Object> resultMap = new HashMap<>();
        if (!userImage.isEmpty()) {
// 获取文件名
            String originalFilename = userImage.getOriginalFilename();
            String
                    suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = DateUtil.getCurrentDateStr() + suffixName;
            String uniappFolderPath = null;
            try {
                // 获取 resources 目录的路径
                String resourcesPath = resourceLoader.getResource("classpath:").getFile().getAbsolutePath();

                // 拼接 uniapp 文件夹的路径
                uniappFolderPath = resourcesPath + File.separator + userImagesFilePath;

                // 创建 Path 对象
                Path uniappFolder = Paths.get(uniappFolderPath);

                // 判断 uniapp 文件夹是否存在
                if (Files.exists(uniappFolder) && Files.isDirectory(uniappFolder)) {
                    System.out.println("uniapp 文件夹已存在");
                } else {
                    // 创建 uniapp 文件夹
                    Files.createDirectory(uniappFolder);
                    System.out.println("uniapp 文件夹创建成功");
                }
            } catch (Exception e) {
                System.out.println("发生异常：" + e.getMessage());
            }
            try {
                FileUtils.copyInputStreamToFile(userImage.getInputStream(), new File(uniappFolderPath, newFileName));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            resultMap.put("userImageFileName", newFileName);
// 更新到数据库

            Claims claims = JwtUtils.validateJWT(token).getClaims();
            QueryWrapper queryWrapper = QueryWrapper.create().where(WxUserInfo::getOpenid).eq(claims.getId());
            WxUserInfo wxUserInfo = new WxUserInfo();
            wxUserInfo.setOpenid(claims.getId());
            wxUserInfo.setAvatarUrl(newFileName);
            boolean update = update(wxUserInfo, queryWrapper);
            if (update) {
                return ResultVO.success(resultMap);
            } else {
                return ResultVO.fail(500, "上传失败");
            }
        }

        return ResultVO.fail(500, "上传失败");
    }

}